package org.springframework.prospring.ticket.web;

import org.springframework.prospring.ticket.service.RegionManager;
import org.springframework.prospring.ticket.service.ClubManager;
import org.springframework.prospring.ticket.service.ReservationFieldRequest;
import org.springframework.prospring.ticket.domain.Club;
import org.springframework.prospring.ticket.domain.Field;
import org.springframework.prospring.ticket.domain.Turn;
import org.springframework.prospring.ticket.domain.location.Region;
import org.springframework.validation.Errors;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.sql.Timestamp;

/**
 * Form controller issuing a ReservationRequest on behalf of the user.
 * The user has selected a show, a price band and a date in the previous
 * screen(s) and this form controller will create the reservation
 * request based on this. Together with the amount of seats the user will
 * be selected, this form controller completes the request.<p>
 *
 * Input:
 * <ul>
 *   <li><code>performanceId</code>: the performance identifier</li>
 *   <li><code>priceBandId</code>: the price band identifier</li>
 * </ul>
 * Error conditions:
 * <ul>
 *  <li>When not enough seats are available anymore</li>
 * </ul>
 */
public class ReserveFieldStep4Controller extends AbstractReservationFieldRequestController {

/*
    // the Region manager service this controller uses.
    private RegionManager regionManager;

    // the Club manager service this controller uses.
    private ClubManager clubManager;
*/

    /*
	 * @see org.springframework.web.servlet.mvc.AbstractFormController#formBackingObject(javax.servlet.http.HttpServletRequest)
	 */
    protected Object formBackingObject(HttpServletRequest request) throws Exception {
        if (logger.isDebugEnabled()) {
            logger.debug("ReserveFieldStep4Controller.formBackingObject");
        }
        return getReservationRequestFromSession(request);
    }

/*
    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
        if (logger.isDebugEnabled()){
            logger.debug("ReserveFieldStep4Controller.handleRequestInternal");
        }


        //ReservationField reservationField = getReservationFromSession(request);
         ReservationFieldRequest reservationFieldRequest = getReservationRequestFromSession(request);


        Collection<Club> clubs = clubManager.findAllClubsByRegionId(reservationFieldRequest.getRegionId());

        // putting the reservation and performance in session, for future reference.
        WebUtils.setSessionAttribute(request, "reservationFieldRequest", reservationFieldRequest);


        ModelAndView mav = new ModelAndView(getSuccessView());
        mav.addObject("regions", reservationFieldRequest.getRegions());
        mav.addObject("clubs", clubs);
        if (logger.isDebugEnabled()) {
            logger.debug("ModelAndView: "+mav.toString());
        }

        return mav;
    }
*/

    /**
     * Binds the maximum number of seats the user will be able to select
     * (key = <code>maximumSeats</code>) and hte default selected value
     * (<code>defaultSelected</code>).
     */
    protected Map referenceData(HttpServletRequest request, Object o, Errors errors) throws Exception {
        if (logger.isDebugEnabled()) {
            logger.debug("ReserveFieldStep4Controller.referenceData");
        }


        ReservationFieldRequest reservationFieldRequest = (ReservationFieldRequest)o;
        Map dataMap = new HashMap();

        Club club = clubManager.findClub(reservationFieldRequest.getClubId());

        Collection<Turn> turns = clubManager.findAllTurnsByFieldIdAndDate(reservationFieldRequest.getFieldId(), reservationFieldRequest.getReservationDate());

        Collection<Turn> turnsByfield = buildAllTurns(reservationFieldRequest.getReservationDate(), club, turns);
        // putting the reservation and performance in session, for future reference.
        //WebUtils.setSessionAttribute(request, "reservationFieldRequest", reservationFieldRequest);


        dataMap.put("regions", reservationFieldRequest.getRegions());
        dataMap.put("turns", turnsByfield);
        return dataMap;
    }

    /**
     * @see org.springframework.web.servlet.mvc.SimpleFormController#onSubmit(
     *      javax.servlet.http.HttpServletRequest,
            javax.servlet.http.HttpServletResponse,
            Object,
            org.springframework.validation.BindException)
     */
    protected ModelAndView onSubmit(HttpServletRequest httpRequest, HttpServletResponse httpResponse,
                                    Object o, BindException errors) throws Exception {
        if (logger.isDebugEnabled()) {
            logger.debug("ReserveFieldStep4Controller.onSubmit");
        }


        // the object is an already filled in reservation reservationFieldRequest
        ReservationFieldRequest reservationFieldRequest = (ReservationFieldRequest)o;


        // if errors occured showing the form view with the error messages.
        if ("sss" == null) {
            return showForm(httpRequest, errors, getFormView());
        }


        Collection<Club> clubs = clubManager.findAllClubsByRegionId(reservationFieldRequest.getRegionId());

        // putting the reservation and performance in session, for future reference.
        //WebUtils.setSessionAttribute(request, "reservationFieldRequest", reservationFieldRequest);


        ModelAndView mav = new ModelAndView(getSuccessView());
        mav.addObject("regions", reservationFieldRequest.getRegions());
        mav.addObject("clubs", clubs);

        /*
        // putting the reservation and performance in session, for future reference.
        WebUtils.setSessionAttribute(httpRequest, "reservationFieldRequest", reservationFieldRequest);

        // redirecting the another controller that will show the reservation.
        // this is done to prevent the user from resubmitting the form.
        reservationFieldRequest.setSuccessView(getSuccessView());

        ModelAndView mav = new ModelAndView(new RedirectView(getSuccessView()));
        if (logger.isDebugEnabled()) {
            logger.debug("ModelAndView: "+mav.toString());
        }
        */
        return mav;
    }


/*
    public RegionManager getRegionManager() {
        return regionManager;
    }

    public void setRegionManager(RegionManager regionManager) {
        this.regionManager = regionManager;
    }


    public ClubManager getClubManager() {
        return clubManager;
    }

    public void setClubManager(ClubManager clubManager) {
        this.clubManager = clubManager;
    }
*/
    //====================================== Helper Method (some used for testing) ====================================


    /**
     * Construye un lista con los turnos de cada cancha, incluyendo los horarios, disponibilidad, etc
     *
     * @param dateForReservation
     * @param club
     * @param reservedTurns
     * @return a list with all turns, availables and not availables turn
     */
    private Collection<Turn> buildAllTurns(Date dateForReservation, Club club, Collection reservedTurns){
        Collection<Turn> turns = new ArrayList();

        Calendar turnCalendar = Calendar.getInstance();
        turnCalendar.setTimeInMillis(club.getOpeningTime().getTime());

        Calendar currentDateCalendar = Calendar.getInstance();
        currentDateCalendar.setTime(dateForReservation);
        currentDateCalendar.set(Calendar.HOUR_OF_DAY, turnCalendar.get(Calendar.HOUR_OF_DAY));
        currentDateCalendar.set(Calendar.MINUTE, turnCalendar.get(Calendar.MINUTE));
        currentDateCalendar.set(Calendar.SECOND, turnCalendar.get(Calendar.SECOND));
        currentDateCalendar.set(Calendar.MILLISECOND, turnCalendar.get(Calendar.MILLISECOND));

        turnCalendar.setTimeInMillis(club.getClosingTime().getTime());

        Calendar closingDateCalendar = Calendar.getInstance();
        closingDateCalendar.setTime(dateForReservation);
        closingDateCalendar.set(Calendar.HOUR_OF_DAY, turnCalendar.get(Calendar.HOUR_OF_DAY));
        closingDateCalendar.set(Calendar.MINUTE, turnCalendar.get(Calendar.MINUTE));
        closingDateCalendar.set(Calendar.SECOND, turnCalendar.get(Calendar.SECOND));
        closingDateCalendar.set(Calendar.MILLISECOND, turnCalendar.get(Calendar.MILLISECOND));
        System.out.println("currentDateCalendar = " + currentDateCalendar.getTime());
        System.out.println("closingDateCalendar = " + closingDateCalendar.getTime());

        while (currentDateCalendar.getTimeInMillis() <= closingDateCalendar.getTimeInMillis()){

            Turn turnAvailable = new Turn();
            turnAvailable.setStartDate(new Timestamp(currentDateCalendar.getTimeInMillis()));
            currentDateCalendar.add(Calendar.HOUR_OF_DAY, 1);
            turnAvailable.setEndDate(new Timestamp(currentDateCalendar.getTimeInMillis()));
            turnAvailable.setAvailable(Boolean.TRUE);

            System.out.println("turnAvailable getStartDate()="+turnAvailable.getStartDate()+", getTime() = " + turnAvailable.getStartDate().getTime());

            for (Iterator<Turn> iterator = reservedTurns.iterator(); iterator.hasNext();) {
                Turn turn1 =  iterator.next();
                System.out.println("turn1.getStartDate()"+turn1.getStartDate()+", getStartDate().getTime() = " + turn1.getStartDate().getTime());
                if ( turnAvailable.getStartDate().getTime() == turn1.getStartDate().getTime()) {
                    System.out.println("iguales ");
                    turn1.setAvailable(Boolean.FALSE);
                    turnAvailable = turn1;

                    break;
                }
            }

            turns.add(turnAvailable);
        }

        for (Iterator<Turn> iterator = turns.iterator(); iterator.hasNext();) {
            Turn turn1 = iterator.next();
            System.out.println("turn1.getId()="+turn1.getId()+", turn1.getStartDate() = " + turn1.getStartDate() + ", turn1.getEndDate() =" + turn1.getEndDate());

        }

        return turns;
    }




}
